﻿using System.Configuration;
using System.ServiceModel.Activation;
using VNet.VisiSuite.BusinessLogic;
using VNet.VisiSuite.Common.Helper;
using VNet.VisiSuite.Common.Resource;
using VNet.VisiSuite.Service.Helper;
using VNet.VisiSuite.Service.Interface;
using VNet.VisiSuite.Service.Contact.Message;
using VNet.VisiSuite.Service.Contact.Message.Base;
using VNet.VisiSuite.Service.Contact.Message.Item;
using System.Collections.Generic;

namespace VNet.VisiSuite.Service
{
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
    public class VNetVisiSuiteService : IVNetVisiSuiteService
    {
        #region Util class
        private static AreaUtil _areaUtil = new AreaUtil();
        private static PlantUtil _plantUtil = new PlantUtil();
        private static CellUtil _cellUtil = new CellUtil();
        private static UserLoginUtil _userUtil = new UserLoginUtil();
        private static ProductUtil _productUtil = new ProductUtil();
        private static ProductionPlanUtil _productionPlanUtil = new ProductionPlanUtil();
        private static SyncUtil _syncUtil = new SyncUtil();

#if DEBUG
        // TODO: Remove the variable below on final build
        private VisiCentralTestDataUtil _visiCentralTestDataUtil = new VisiCentralTestDataUtil();
#endif
        #endregion

        #region Plants
        public GetDataResponse<IList<PlantItem>> GetPlants(GetDataRequest request)
        {
            request.ValidateInput("Get Plants");
            return _plantUtil.GetPlants(request);
        }

        public SaveDataResponse<IList<PlantItem>> UpdatePlants(SavePlantRequest request)
        {
            request.ValidateInput("Update Plants");
            return _plantUtil.UpdatePlants(request);
        }

        public SaveDataResponse<PlantItem> UpdatePlant(SaveDataRequest<PlantItem> request)
        {
            request.ValidateInput("Update Plant");
            return _plantUtil.UpdatePlant(request);
        }

        public SaveDataResponse<PlantItem> InsertPlant(SaveDataRequest<PlantItem> request)
        {
            request.ValidateInput("Insert Plant");
            return _plantUtil.InsertPlant(request);
        }

        public DeleteDataResponse DeletePlant(DeleteDataRequest request)
        {
            request.ValidateInput("Delete Plant");
            return _plantUtil.DeletePlant(request);
        }
        #endregion

        #region Users
        public DeleteDataResponse DeleteUser(DeleteDataRequest request)
        {
            request.ValidateInput("Delete User");

            return _userUtil.DeleteUser(request);
        }
        
        public GetDataResponse<IList<UserLoginItem>> GetUsers(GetDataRequest request)
        {
            request.ValidateInput("Get Users");

            return _userUtil.GetUsers(request);
        }

        public SaveDataResponse<UserLoginItem> UpdateUser(SaveDataRequest<UserLoginItem> request)
        {
            request.ValidateInput("Update User");

            return _userUtil.UpdateUser(request);
        }

        public SaveDataResponse<UserLoginItem> InsertUser(SaveDataRequest<UserLoginItem> request)
        {
            request.ValidateInput("Insert User");

            return _userUtil.InsertUser(request);
        }

        #endregion

        #region Products

        public GetDataResponse<IList<ProductItem>> GetProducts(GetDataRequest request)
        {
            request.ValidateInput("Get Products");

            return _productUtil.GetProducts(request);
        }

        public SaveDataResponse<ProductItem> UpdateProduct(SaveDataRequest<ProductItem> request)
        {
            request.ValidateInput("Update Product");

            return _productUtil.UpdateProduct(request);
        }

        public SaveDataResponse<ProductItem> InsertProduct(SaveDataRequest<ProductItem> request)
        {
            request.ValidateInput("Insert Product");

            return _productUtil.InsertProduct(request);
        }

        public SaveDataResponse<IList<ProductItem>> ImportProducts(SaveDataRequest<IList<ProductItem>> request)
        {
            request.ValidateInput("Import Product");

            return _productUtil.ImportProducts(request);
        }
        
        public DeleteDataResponse DeleteProduct(DeleteDataRequest request)
        {
            request.ValidateInput("Delete Product");

            return _productUtil.DeleteProduct(request);
        }

        #endregion

        #region Production Plan

        public GetDataResponse<IList<ProductionPlanItem>> GetProductionPlans(GetDataRequest request)
        {
            request.ValidateInput("Get Production Plans");

            return _productionPlanUtil.GetProductionPlans(request);
        }

        public SaveDataResponse<ProductionPlanItem> UpdateProductionPlan(SaveDataRequest<ProductionPlanItem> request)
        {
            request.ValidateInput("Update Production Plan");

            return _productionPlanUtil.UpdateProductionPlan(request);
        }

        public SaveDataResponse<ProductionPlanItem> InsertProductionPlan(SaveDataRequest<ProductionPlanItem> request)
        {
            request.ValidateInput("Insert Production Plan");

            return _productionPlanUtil.InsertProductionPlan(request);
        }

        public SaveDataResponse<IList<ProductionPlanItem>> ImportProductionPlans(SaveDataRequest<IList<ProductionPlanItem>> request)
        {
            request.ValidateInput("Import Production Plan");

            return _productionPlanUtil.ImportProductionPlans(request);
        }

        public DeleteDataResponse DeleteProductionPlan(DeleteDataRequest request)
        {
            request.ValidateInput("Delete Production Plan");
            return _productionPlanUtil.DeleteProductionPlan(request);
        }


        public GetDataResponse<ProductionPlanReferenceItem> GetProductionPlanReference(GetDataRequest request)
        {
            request.ValidateInput("Get Production Plan Reference");

            return _productionPlanUtil.GetProductionPlanReference(request);
        }


        #endregion

        #region Areas

        #region Area
        public SaveDataResponse<AreaItem> UpdateArea(SaveDataRequest<AreaItem> request)
        {
            request.ValidateInput("Update Area");
            return _areaUtil.UpdateArea(request);
        }

        public SaveDataResponse<AreaItem> InsertArea(SaveDataRequest<AreaItem> request)
        {
            request.ValidateInput("Insert Area");
            return _areaUtil.InsertArea(request);
        }

        public DeleteDataResponse DeleteArea(DeleteDataRequest request)
        {
            request.ValidateInput("Delete AreaShift");
            return _areaUtil.DeleteArea(request);
        }
        #endregion

        #region AreaShift
        public GetDataResponse<IList<AreaShiftItem>> GetAreaShifts(GetDataRequest request)
        {
            request.ValidateInput("Get AreaShifts");
            return _areaUtil.GetAreaShifts(request);
        }

        public SaveDataResponse<AreaShiftItem> InsertAreaShift(SaveDataRequest<AreaShiftItem> request)
        {
            request.ValidateInput("Insert AreaShift");
            return _areaUtil.InsertAreaShift(request);
        }

        public SaveDataResponse<AreaShiftItem> UpdateAreaShift(SaveDataRequest<AreaShiftItem> request)
        {
            request.ValidateInput("Update AreaShift");
            return _areaUtil.UpdateAreaShift(request);
        }

        public DeleteDataResponse DeleteAreaShift(DeleteDataRequest request)
        {
            request.ValidateInput("Delete AreaShift");
            return _areaUtil.DeleteAreaShift(request);
        }
        #endregion

        #region LaunchApplication
        public GetDataResponse<IList<LaunchApplicationItem>> GetLaunchApplications(GetDataRequest request)
        {
            request.ValidateInput("Get LaunchApplications");
            return _areaUtil.GetLaunchApplications(request);
        }

        public SaveDataResponse<LaunchApplicationItem> UpdateLaunchApplication(SaveDataRequest<LaunchApplicationItem> request)
        {
            request.ValidateInput("Update LaunchApplication");
            return _areaUtil.UpdateLaunchApplication(request);
        }

        public SaveDataResponse<LaunchApplicationItem> InsertLaunchApplication(SaveDataRequest<LaunchApplicationItem> request)
        {
            request.ValidateInput("Insert LaunchApplication");
            return _areaUtil.InsertLaunchApplication(request);
        }

        public DeleteDataResponse DeleteLaunchApplication(DeleteDataRequest request)
        {
            request.ValidateInput("Delete LaunchApplication");
            return _areaUtil.DeleteLaunchApplication(request);
        }

        public SaveDataResponse<IList<LaunchApplicationItem>> MoveLaunchApplication(SaveDataRequest<LaunchApplicationItem> request)
        {
            request.ValidateInput("Move LaunchApplication");

            return _areaUtil.MoveLaunchApplication(request);
        }

        #endregion

        #region Reason Code
        public GetDataResponse<IList<ReasonCodeItem>> GetReasonCodes(GetDataRequest request)
        {
            request.ValidateInput("Get ReasonCodes");
            return _areaUtil.GetReasonCodes(request);
        }

        public SaveDataResponse<ReasonCodeItem> InsertReasonCode(SaveDataRequest<ReasonCodeItem> request)
        {
            request.ValidateInput("Insert ReasonCode");
            return _areaUtil.InsertReasonCode(request);
        }

        public SaveDataResponse<ReasonCodeItem> UpdateReasonCode(SaveDataRequest<ReasonCodeItem> request)
        {
            request.ValidateInput("Update ReasonCode");
            return _areaUtil.UpdateReasonCode(request);
        }

        public DeleteDataResponse DeleteReasonCode(DeleteDataRequest request)
        {
            request.ValidateInput("Delete ReasonCode");
            return _areaUtil.DeleteReasonCode(request);
        }

        public GetDataResponse<IList<RollupDefinitionItem>> GetRollupDefinitionsAsSource(GetDataRequest request)
        {
            request.ValidateInput("Get RollupDefinitions As Source");
            return _areaUtil.GetRollupDefinitionsAsSource(request);
        }

        #endregion

        #region RollupDefinition
        public GetDataResponse<IList<RollupDefinitionItem>> GetRollupDefinitions(GetDataRequest request)
        {
            request.ValidateInput("Get RollupDefinitions");
            return _areaUtil.GetRollupDefinitions(request);
        }

        public SaveDataResponse<RollupDefinitionItem> InsertRollupDefinition(SaveDataRequest<RollupDefinitionItem> request)
        {
            request.ValidateInput("Insert RollupDefinition");
            return _areaUtil.InsertRollupDefinition(request);
        }

        public SaveDataResponse<RollupDefinitionItem> UpdateRollupDefinition(SaveDataRequest<RollupDefinitionItem> request)
        {
            request.ValidateInput("Update RollupDefinition");
            return _areaUtil.UpdateRollupDefinition(request);
        }

        public DeleteDataResponse DeleteRollupDefinition(DeleteDataRequest request)
        {
            request.ValidateInput("Delete RollupDefinition");
            return _areaUtil.DeleteRollupDefinition(request);
        }

        public SaveDataResponse<IList<RollupDefinitionItem>> MoveRollupDefinition(SaveDataRequest<RollupDefinitionItem> request)
        {
            request.ValidateInput("Move RollupDefinition");

            return _areaUtil.MoveRollupDefinition(request);
        }

        #endregion

        #region AlarmSetting
        public GetDataResponse<IList<AlarmSettingItem>> GetAlarmSettings(GetDataRequest request)
        {
            request.ValidateInput("Get AlarmSettings");
            return _areaUtil.GetAlarmSettings(request);
        }

        public SaveDataResponse<AlarmSettingItem> InsertAlarmSetting(SaveDataRequest<AlarmSettingItem> request)
        {
            request.ValidateInput("Insert AlarmSetting");
            return _areaUtil.InsertAlarmSetting(request);
        }

        public SaveDataResponse<AlarmSettingItem> UpdateAlarmSetting(SaveDataRequest<AlarmSettingItem> request)
        {
            request.ValidateInput("Update AlarmSetting");
            return _areaUtil.UpdateAlarmSetting(request);
        }

        public DeleteDataResponse DeleteAlarmSetting(DeleteDataRequest request)
        {
            request.ValidateInput("Delete AlarmSetting");
            return _areaUtil.DeleteAlarmSetting(request);
        }
        
        #endregion

        #region Reason Code
        public GetDataResponse<IList<ReasonCodeItem>> GetScrapReasonCodes(GetDataRequest request)
        {
            request.ValidateInput("Get ScrapReasonCodes");
            return _areaUtil.GetScrapReasonCodes(request);
        }

        #endregion

        #region Scheduled Downtime

        public GetDataResponse<IList<ScheduledDowntimeItem>> GetScheduledDowntimes(GetDataRequest request)
        {
            request.ValidateInput("Get ScheduledDowntimes");
            return _areaUtil.GetScheduledDowntimes(request);
        }

        public SaveDataResponse<ScheduledDowntimeItem> UpdateScheduledDowntime(SaveDataRequest<ScheduledDowntimeItem> request)
        {
            request.ValidateInput("Update ScheduledDowntimes");
            return _areaUtil.UpdateScheduledDowntime(request);
        }

        public SaveDataResponse<ScheduledDowntimeItem> InsertScheduledDowntime(SaveDataRequest<ScheduledDowntimeItem> request)
        {
            request.ValidateInput("Insert Scheduled Downtime");
            return _areaUtil.InsertScheduleTime(request);
        }

        public DeleteDataResponse DeleteScheduledDowntime(DeleteDataRequest request)
        {
            request.ValidateInput("Delete Scheduled Downtime");
            return _areaUtil.DeleteSchedulerdDowntime(request);
        }

        #endregion

        #region Scheduled Downtime

        public GetDataResponse<IList<ScheduledRepeatItem>> GetScheduledRepeat(GetDataRequest request)
        {
            request.ValidateInput("Get Scheduled Repeat");
            return _areaUtil.GetScheduledRepeat(request);
        }

        public SaveDataResponse<ScheduledRepeatItem> UpdateScheduleRepeat(SaveDataRequest<ScheduledRepeatItem> request)
        {
            request.ValidateInput("Update Scheduled Repeat");
            return _areaUtil.UpdateScheduleRepeat(request);
        }

        public SaveDataResponse<ScheduledRepeatItem> InsertScheduleRepeat(SaveDataRequest<ScheduledRepeatItem> request)
        {
            request.ValidateInput("Insert Scheduled Repeat");
            return _areaUtil.InsertScheduleRepeat(request);
        }

        public DeleteDataResponse DeleteScheduledRepeat(DeleteDataRequest request)
        {
            request.ValidateInput("Delete Scheduled Repeat");
            return _areaUtil.DeleteScheduledRepeat(request);
        }

        #endregion


        #endregion

        #region Cell
        public SaveDataResponse<CellItem> UpdateCell(SaveDataRequest<CellItem> request)
        {
            request.ValidateInput("Update Cell");
            return _cellUtil.UpdateCell(request);
        }

        public SaveDataResponse<CellItem> InsertCell(SaveDataRequest<CellItem> request)
        {
            request.ValidateInput("Insert Cell");
            return _cellUtil.InsertCell(request);
        }

        public DeleteDataResponse DeleteCell(DeleteDataRequest request)
        {
            request.ValidateInput("Delete CellShift");
            return _cellUtil.DeleteCell(request);
        }
        #endregion

        #region Sync

        public ConfigureResponse VerifyCellAndGetServerData(ConfigureRequest request)
        {
            var ip = IpAddressHelper.GetVisitorIpAddress();

            // Validate request without security
            request.RequiredNotNull();

            //validate registry InstakKey againts web.config
            if (request.InstallKey != ConfigurationManager.AppSettings["InstallKey"])
                return new ConfigureResponse { Success = false, Error = new ServiceError { ErrorCode = "Error InstallKey", Description = ErrorMessages.InstallKeyInvalid } };

            // Call to business layer to get data after sign in action
            return _syncUtil.VerifyCellAndGetServerData(request);
        }

        public ConfigureResponse SyncDataFromServerToClient(ConfigureRequest request)
        {
            var ip = IpAddressHelper.GetVisitorIpAddress();

            // Validate request without security
            request.ValidateInput("Sync Data From Server To Client");

            return _syncUtil.SyncDataFromServerToClient(request);
        }

        public SyncDataFromClientResponse SyncDataFromClientToServer(SyncDataFromClientRequest request)
        {
            // Validate request without security
            request.ValidateInput("Sync Data From Client To Server");

            // Call to business layer to get data after sign in action
            return _syncUtil.SyncDataFromClientToServer(request);
        }

        #endregion
        
        #region VisiCentral

        public GetDataResponse<IList<CellItem>> GetCells(GetDataRequest request)
        {
            //request.ValidateInput("Get Cells");
            return _cellUtil.GetCells(request);
        }

        public ProductionDataResponse GetProductionData(ProductionDataRequest request)
        {
            //request.ValidateInput("GetProductionData");
            return ProductionDataUtil.GetProductionData(request);
        }

        public AnalysisChartDataResponse GetAnalysisChartData(AnalysisChartDataRequest request)
        {
            // TODO: Implement Analysis Chart Data here
            return new AnalysisChartDataResponse();
        }

        #endregion

#if DEBUG

        // TODO: Remove this region below on final build.
        #region VisiCentral Test Data

        /// <summary>
        /// Creates the initial data test for Visi Central application.
        /// </summary>
        /// <returns></returns>
        public GetDataResponse<bool> CreateDataTest()
        {
            return _visiCentralTestDataUtil.CreateDataTest("001");
        }

        /// <summary>
        /// Creates the production history (test data) at time interval for Visi Central application.
        /// </summary>
        /// <returns></returns>
        public GetDataResponse<bool> CreateProductionHistoryAtInterval()
        {
            return _visiCentralTestDataUtil.CreateProductionHistoryAtInterval("001");
        }

        #endregion

#endif
    }
}